/*                                                                                                                                               
 *  Copyright (c) 2012 Shirou Maruyama                                                                                                           
 *                                                                                                                                               
 *   Redistribution and use in source and binary forms, with or without                                                                          
 *   modification, are permitted provided that the following conditions                                                                          
 *   are met:                                                                                                                                    
 *                                                                                                                                               
 *   1. Redistributions of source code must retain the above Copyright                                                                           
 *      notice, this list of conditions and the following disclaimer.                                                                            
 *                                                                                                                                               
 *   2. Redistributions in binary form must reproduce the above Copyright                                                                        
 *      notice, this list of conditions and the following disclaimer in the                                                                      
 *      documentation and/or other materials provided with the distribution.                                                                     
 *                                                                                                                                               
 *   3. Neither the name of the authors nor the names of its contributors                                                                        
 *      may be used to endorse or promote products derived from this                                                                             
 *      software without specific prior written permission.                                                                                      
 */

#ifndef DICTIONARY_HPP_
#define DICTIONARY_HPP_

#include <vector>
#include <string>
#include <stdint.h>

namespace pacbeep {

const uint32_t kDummy = (4294967295U);

typedef struct rule_info {
  rule_info(): code(kDummy), left(kDummy), 
	       right(kDummy), cnt(kDummy) {}
  rule_info(uint32_t _code, uint32_t _left, 
	    uint32_t _right, uint32_t _cnt) : 
    code(_code), left(_left), 
    right(_right), cnt(_cnt) {}
  uint32_t code;
  uint32_t left;
  uint32_t right;
  uint32_t cnt;
} RULE;

class DICT {
public:
  DICT(): Delta_(0), N_(0), K_(0), NumRules_(0), 
          Rules_(), DictSize_(0), EntrySize_(0) {}
  void Init(uint64_t k);
  bool GetCode(uint32_t left, uint32_t right, uint32_t& code);
  uint32_t AddRule(uint32_t left, uint32_t right);
  uint32_t DictSize() { return DictSize_; }

private:
  uint32_t Delta_;
  uint64_t N_;
  uint64_t K_;
  uint32_t NumRules_;
  std::vector<std::vector<RULE> > Rules_;
  uint32_t DictSize_;
  uint32_t EntrySize_;

  uint32_t ReverseAccess(uint32_t left, uint32_t right);
  void ReDict();
  void ReHash();
  uint32_t ComputeHashVal(const uint32_t left, const uint32_t right) const;

}; // class DICT

} // namespace pacbeep

#endif // DICTIONARY_HPP_
